# -*- coding: utf8 -*-
from multiprocessing import Pool
from .beidou_code_point import beidou_grid_code_point
import os
from lat_lon_parser import parse
from .beidou_northeast_hemisphere import transform_longitude_latitude
from .beidou_northeast_hemisphere import geosot_grid_size_list
from .beidou_northeast_hemisphere import beidou_grid_encoding
from .tool import range_float, generate_points, judge_point_in_polygon


def _beidou_code_point(point, longitude_polygon, latitude_polygon, level_n):
    result = judge_point_in_polygon(point, longitude_polygon, latitude_polygon)
    longitude, latitude = point
    if result:
        grid_encode = beidou_grid_encoding(longitude, latitude, level_n)
        return longitude, latitude, grid_encode
    else:
        return longitude, latitude, None


def beidou_grid_code_polygon(longitudeList, latitudeList, level_n, parralel=False):
    """
    给出多边形边上线的经纬度表示，构造成多边形。要求经纬度以字符串样式传入，并且逗号分割。经纬度相对应 (long1,lat1),(long2,lat2),(long3,lat3)
    如果最后一个坐标点与第一个坐标点不相同，默认多加一个第一个点，代表的是闭环
    :param parralel: bool
    :param longitudeList: str , seperator ; ,demo: "long1;long2;long3"
    :param latitudeList: str , seperator ; ,demo: "lat1;lat2;lat3"
    :param level_n: int , [1,10]
    :return:
    """
    longitude_list = longitudeList.split(';')
    latitude_ist = latitudeList.split(';')
    try:
        assert len(longitude_list) == len(latitude_ist)
    except:
        raise Exception(f'parse argument error,please check,{longitudeList}||{latitudeList}')
    else:
        for longitude, latitude in zip(longitude_list, latitude_ist):
            point = (longitude, latitude)
            try:
                longitude_float = parse(longitude)
                latitude_float = parse(latitude)
            except:
                raise Exception(f'point format error,please check point {point}')
            else:
                try:
                    assert longitude_float >= 0 and latitude_float >= 0
                except:
                    raise Exception(f'只能处理东北半球的经纬度点，{point}')
    # 判断一下是否是个闭环
    if (longitude_list[0] == longitude_list[-1]) and (latitude_ist[0] == latitude_ist[-1]):
        pass
    else:
        longitude_list.append(longitude_list[0])
        latitude_ist.append(latitude_ist[0])
    # format longitude and latitude
    longitude_list_format = [transform_longitude_latitude(longitude) for longitude in longitude_list]
    latitude_list_format = [transform_longitude_latitude(latitude) for latitude in latitude_ist]
    # grid size
    grid_long, grid_lat = geosot_grid_size_list[level_n]
    # generate point
    longitude_min, longitude_max = min(longitude_list_format), max(longitude_list_format)
    latitude_min, latitude_max = min(latitude_list_format), max(latitude_list_format)
    longitude_grid_point_list = list(range_float(longitude_min, longitude_max, grid_long))
    latitude_grid_point_list = list(range_float(latitude_min, latitude_max, grid_lat))
    point_list_format = generate_points(longitude_grid_point_list, latitude_grid_point_list)
    # 并行处理或单步处理
    if parralel:
        pool = Pool(os.cpu_count())
        results = []
        for point in point_list_format:
            res = pool.apply_async(_beidou_code_point,
                                   args=(point, longitude_list_format, latitude_list_format, level_n))
            results.append(res)
        pool.close()
        pool.join()
        grid_code_result = [res.get() for res in results]
        pool.terminate()
        grid_code_list = [point[2] for point in grid_code_result if point[2] is not None]
    else:
        grid_code_result = [_beidou_code_point(point, longitude_list_format, latitude_list_format, level_n) for point in
                            point_list_format]
        grid_code_list = [point[2] for point in grid_code_result if point[2] is not None]

    grid_code_set = list(set(grid_code_list))
    return grid_code_set


if __name__ == '__main__':
    pass
